package com.jade.editor.domain.parts;

import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.MouseTrackAdapter;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Device;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.wb.swt.SWTResourceManager;

public class Ruler {
	
	private int _metric = DrawArea.METRIC_PX;
	private Composite _parent;
	private Composite _drawArea;
//	private int _zoom = 0;
	private int _bigStep = 50;
	private int _lilStep = 5;
	private boolean _vertTrack = false;
	private boolean _horzTrack = false;
	private Composite _rulerNull;
	private Composite _leftRuler;
	private Composite _upperRuler;
	
	public Ruler(Composite parent, Composite drawArea, int metric, int zoom){
		_parent = parent;
		_metric = metric;
//		_zoom = zoom;
		_drawArea = drawArea;
	}
	
	public Ruler(Composite parent, int metric){
		_parent = parent;
		_metric = metric;
	}
	
	public Ruler(int metric){
		_metric = metric;
	}
	
	public void setVisible(boolean b){
		_rulerNull.setVisible(b);
		_upperRuler.setVisible(b);
		_leftRuler.setVisible(b);
	}
	
	public void drawRuler(Composite parent, Composite drawArea){
		_parent = parent;
		_drawArea = drawArea;
		_rulerNull = new Composite(_parent, SWT.NONE);
		_rulerNull.setBackground(SWTResourceManager.getColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND_GRADIENT));
		_rulerNull.setBounds(0, 0, 20, 20);
		_rulerNull.addPaintListener(new PaintListener() {
			public void paintControl(PaintEvent e) {
			
				if (_metric == DrawArea.METRIC_PX)
					e.gc.drawString("px", 1, 1);
				else if (_metric == DrawArea.METRIC_MM)
					e.gc.drawString("mm", 1, 1);
				else if (_metric == DrawArea.METRIC_CM)
					e.gc.drawString("cm", 1, 1);
	
			}
		});
		
		_rulerNull.addMouseTrackListener(new MouseTrackAdapter() {
			@Override
			public void mouseEnter(MouseEvent e) {
				_rulerNull.setBackground(SWTResourceManager.getColor(SWT.COLOR_TITLE_BACKGROUND_GRADIENT));
			}
			@Override
			public void mouseExit(MouseEvent e) {
				_rulerNull.setBackground(SWTResourceManager.getColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND_GRADIENT));
			}
		});
		

		
		Label separatorV1 = new Label(_rulerNull, SWT.SEPARATOR | SWT.VERTICAL);
		separatorV1.setBounds(19, 0, 2, 20);
		
		Label separatorH1 = new Label(_rulerNull, SWT.SEPARATOR | SWT.HORIZONTAL);
		separatorH1.setBounds(0, 19, 20, 2);
		
		_leftRuler = new Composite(_parent, SWT.NONE);
		_leftRuler.setBackground(SWTResourceManager.getColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND_GRADIENT));
		_leftRuler.setBounds(0, 20, 20, 550);
		
		final Label separatorH1l = new Label(_leftRuler, SWT.SEPARATOR | SWT.VERTICAL);
		separatorH1l.setBounds(19, 0, 2, 500);
		
		_upperRuler = new Composite(_parent, SWT.NONE);
		_upperRuler.setBackground(SWTResourceManager.getColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND_GRADIENT));
		_upperRuler.setBounds(20, 0, 531, 20);
		
		final Label separatorV1u = new Label(_upperRuler, SWT.SEPARATOR | SWT.HORIZONTAL);
		separatorV1u.setBounds(0, 19, 500, 2);
		
		_parent.addControlListener(new ControlAdapter() {
			@Override
			public void controlResized(final ControlEvent e) {

				_upperRuler.setBounds(20, 0, _parent.getSize().x - 20, 20);
				separatorV1u.setBounds(0, 19, _upperRuler.getSize().x, 2);
				_leftRuler.setBounds(0, 20, 20, _parent.getSize().y - 20);
				separatorH1l.setBounds(19, 0, 2, _leftRuler.getSize().y);
				_leftRuler.redraw();
				
				}
			});
		

		
		
		_leftRuler.addPaintListener(new PaintListener(){
			public void paintControl (PaintEvent e) {
				
				if (_metric == DrawArea.METRIC_PX){
					
					int lengthY = _leftRuler.getSize().y;
					int countY = lengthY / _bigStep;
					
					for (int i = 0, y = 0; i <= countY; i++, y += _bigStep){
						e.gc.drawLine(3, y , 20, y);
						String txt = "" + y;
						drawVerticalText(txt, 0, y, e.gc, SWT.UP);
					}
					
					int countY2 = lengthY / _lilStep;
					for (int i = 0, y = 0; i <= countY2; i++, y += _lilStep){
						e.gc.drawLine(15, y , 20, y);
					}
					
				}

				else if (_metric == DrawArea.METRIC_CM){
					
					Device device = _leftRuler.getDisplay();
					double cmInpx = device.getDPI().x/2.56;
					
					int bigStep = (int) (Math.rint(100.0 * cmInpx)/100.0);
					
					int lengthY = _leftRuler.getSize().y;
					int countY = lengthY / bigStep;
					
					for (int i = 0, y = 0; i <= countY; i++, y += bigStep){
						e.gc.drawLine(3, y , 20, y);
						for(int j = 0, y2 = y; j < 10; j++, y2 += 4){
							e.gc.drawLine(15, y2 , 20, y2);
						}

						String txt = "" + i;
						drawVerticalText(txt, 0, y, e.gc, SWT.UP);
					}
					
				}
				
			}
		});
		
		_upperRuler.addPaintListener(new PaintListener(){
			public void paintControl (PaintEvent e) {
				
				if (_metric == DrawArea.METRIC_PX){
					
					int lengthX = _upperRuler.getSize().x;
					int countX = lengthX / _bigStep;
					
					for (int i = 0, x = 0; i <= countX; i++, x += _bigStep){
						e.gc.drawLine(x, 3 , x, 20);
						String txt = "" + x;
						drawHorizontalText(txt, x, 0, e.gc);
					}
					
					int countX2 = lengthX / _lilStep;
					for (int i = 0, x = 0; i <= countX2; i++, x += _lilStep){
						e.gc.drawLine(x, 15 , x, 20);
					}
					
				}
				else if (_metric == DrawArea.METRIC_CM){
					
					Device device = _leftRuler.getDisplay();
					double cmInpx = device.getDPI().x/2.56;
					
					int bigStep = (int) (Math.rint(100.0 * cmInpx)/100.0);
					
					int lengthX = _upperRuler.getSize().x;
					int countX = lengthX / bigStep;
					
					for (int i = 0, x = 0; i <= countX; i++, x += bigStep){
						e.gc.drawLine(x, 3 , x, 20);
						for(int j = 0, x2 = x; j < 10; j++, x2 += 4){
							e.gc.drawLine(x2, 15 , x2, 20);
						}

						String txt = "" + i;
						drawHorizontalText(txt, x, 0, e.gc);
					}
					
//					double mmInpx = device.getDPI().x/25.6;
//					int lilStep = (int) (Math.rint(100.0 * mmInpx)/100.0);
//					int countX2 = lengthX / lilStep;
//					for (int i = 0, x = 0; i <= countX2; i++, x += lilStep){
//						e.gc.drawLine(x, 15 , x, 20);
//					}
					
				}
				
			}
		});
		

		
		final Composite upMv = new Composite(_upperRuler, SWT.NONE);
		upMv.setBackground(SWTResourceManager.getColor(SWT.COLOR_RED));
		upMv.setBounds(0, 10, 2, 10);
		upMv.setVisible(false);
		
		final Composite ltMv = new Composite(_leftRuler, SWT.NONE);
		ltMv.setBackground(SWTResourceManager.getColor(SWT.COLOR_RED));
		ltMv.setBounds(10, 190, 10, 2);
		ltMv.setVisible(false);
		
		_drawArea.addMouseMoveListener(new MouseMoveListener() {
			public void mouseMove(MouseEvent e) {
				if (_vertTrack)
					ltMv.setLocation(10, e.y);
				if (_horzTrack)
					upMv.setLocation(e.x, 10);
			}
		});
		
		_rulerNull.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseUp(MouseEvent e) {
				
				if((e.x <= _rulerNull.getSize().x) && (e.y <= _rulerNull.getSize().y)){
					SettingsRuler sr = new SettingsRuler(_rulerNull.getShell(), _bigStep, _lilStep, _metric, _vertTrack, _horzTrack);
					sr.open();
					if(sr.getReturnCode() == Window.OK){
						_bigStep = sr.getBigStep();
						_lilStep = sr.getLilStep();
						_metric = sr.getMertic();
						_vertTrack = sr.getVerticalTrack();
						_horzTrack = sr.getHorizontalTrack();
						upMv.setVisible(_horzTrack);
						ltMv.setVisible(_vertTrack);
						_rulerNull.redraw();
						_upperRuler.redraw();
						_leftRuler.redraw();
					}
				}
			}
		});
		
	}
	
	private void drawVerticalText(String string, int x, int y, GC gc, int style) {
    Display display = Display.getCurrent();
    if (display == null) SWT.error(SWT.ERROR_THREAD_INVALID_ACCESS);

    // determine string's dimensions
    gc.setFont(SWTResourceManager.getFont("Segoe UI", 7, SWT.NORMAL));
    Point pt = gc.textExtent(string);
    // create an image the same size as the string
    Image stringImage = new Image(display, pt.x, pt.y);
    // create a GC so we can draw the image
    GC stringGc = new GC(stringImage);

    // set attributes from the original GC to the new GC
    stringGc.setForeground(gc.getForeground());
    stringGc.setBackground(gc.getBackground());
    stringGc.setFont(gc.getFont());

    stringGc.drawText(string, 0, 0);
    
    int mv = stringImage.getImageData().width / 2;
    
    drawVerticalImage(stringImage, x, y - mv, gc, style);
    stringGc.dispose();
    stringImage.dispose();
}
    
    
    private void drawVerticalImage(Image image, int x, int y, GC gc,
            int style) {
    Display display = Display.getCurrent();
    if (display == null) SWT.error(SWT.ERROR_THREAD_INVALID_ACCESS);

    // use the image's data to create a rotated image's data
    ImageData sd = image.getImageData();
    ImageData dd = new ImageData(sd.height, sd.width, sd.depth, sd.palette);
    // determine which way to rotate, depending on up or down
    boolean up = (style & SWT.UP) == SWT.UP;

    // run through the horizontal pixels
    for (int sx = 0; sx < sd.width; sx++) {
            // run through the vertical pixels
            for (int sy = 0; sy < sd.height; sy++) {
                    // determine where to move pixel to in destination image data
                    int dx = up ? sy : sd.height - sy - 1;
                    int dy = up ? sd.width - sx - 1 : sx;
                    // swap the x, y source data to y, x in the destination
                    dd.setPixel(dx, dy, sd.getPixel(sx, sy));
            }
    }
    Image vertical = new Image(display, dd);
    gc.drawImage(vertical, x, y);
    vertical.dispose();
}
    
	private void drawHorizontalText(String string, int x, int y, GC gc) {
	    Display display = Display.getCurrent();
	    if (display == null) SWT.error(SWT.ERROR_THREAD_INVALID_ACCESS);

	    // determine string's dimensions
	    gc.setFont(SWTResourceManager.getFont("Segoe UI", 7, SWT.NORMAL));
	    Point pt = gc.textExtent(string);
	    // create an image the same size as the string
	    Image stringImage = new Image(display, pt.x, pt.y);
	    // create a GC so we can draw the image
	    GC stringGc = new GC(stringImage);

	    // set attributes from the original GC to the new GC
	    stringGc.setForeground(gc.getForeground());
	    stringGc.setBackground(gc.getBackground());
	    stringGc.setFont(gc.getFont());

	    stringGc.drawText(string, 0, 0);
	    
	    int mv = stringImage.getImageData().width / 2;
	    gc.drawImage(stringImage, x-mv, y);
	   // drawVerticalImage(stringImage, x, y - mv, gc, style);
	    stringGc.dispose();
	    stringImage.dispose();
	}
	
}
